package com.ljh.localmusic.runtime

import android.Manifest
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.pager.VerticalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.QueueMusic
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Snackbar
import androidx.compose.material3.SnackbarDefaults
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.LottieConstants
import com.airbnb.lottie.compose.rememberLottieAnimatable
import com.airbnb.lottie.compose.rememberLottieComposition
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.isGranted
import com.google.accompanist.permissions.rememberPermissionState
import com.ljh.localmusic.ui.theme.LocalMusicTheme
import com.ljh.localmusic.R
import com.ljh.localmusic.data.local.models.AudioItem
import com.ljh.localmusic.ui.HomeViewModel
import com.ljh.localmusic.ui.MusicUiEvent
import com.ljh.localmusic.ui.MusicUiEvent.Backward
import com.ljh.localmusic.ui.MusicUiEvent.Forward
import com.ljh.localmusic.ui.MusicUiEvent.PlayPause
import com.ljh.localmusic.ui.MusicUiEvent.RefreshMessage
import com.ljh.localmusic.ui.MusicUiEvent.SeekToNext
import com.ljh.localmusic.ui.MusicUiEvent.SeekToPrevious
import com.ljh.localmusic.ui.component.MusicItemComponent
import com.ljh.localmusic.ui.component.MusicListDialog
import com.ljh.localmusic.ui.service.PlaybackService
import com.ljh.localmusic.utils.MusicStates
import com.ljh.localmusic.utils.ext.logd
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
    private var isServiceRunning = false

    private fun getPermission() {
        val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
            data = Uri.fromParts("package", packageName, null)
        }
        this.startActivity(intent)
    }

    @OptIn(ExperimentalPermissionsApi::class, ExperimentalMaterial3Api::class)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        "activity onCreate".logd()
        setContent {
            val viewModel = hiltViewModel<HomeViewModel>()
            val musicListState by viewModel.musicListState.collectAsStateWithLifecycle()
            var showListDialog by remember { mutableStateOf(false) }

            val snackbarHostState = remember { SnackbarHostState() }
            var msg by remember { mutableStateOf("") }

//            val musicState by viewModel.musicStates.collectAsStateWithLifecycle()
            val isPlaying by viewModel.isPlaying.collectAsStateWithLifecycle()
            val currentPosition by viewModel.currentPosition.collectAsStateWithLifecycle()
            val autoNext by viewModel.autoNext.collectAsStateWithLifecycle()
            val mediaItemIndex by viewModel.mediaItemIndex.collectAsStateWithLifecycle()

            val imageModel by viewModel.imageModel.collectAsStateWithLifecycle()
            val toastMsg by viewModel.toastMsg.collectAsStateWithLifecycle()

            val isLoading by viewModel.isDataLoading.collectAsStateWithLifecycle()

            LaunchedEffect(msg) {
                if (msg.isNotEmpty()) {
                    snackbarHostState.showSnackbar(msg)
                    msg = ""
                } else if (toastMsg.isNotEmpty()) {
                    snackbarHostState.showSnackbar(toastMsg)
                    viewModel.onUiEvent(RefreshMessage(""))
                }
            }

            LaunchedEffect(isPlaying) {
                if (isPlaying) {
                    startMusicService()
                }
            }

            val virtualPageCount = remember { Int.MAX_VALUE }
            val realPageCount = remember(musicListState) { musicListState.size }

            val initialVirtualPage = remember { virtualPageCount / 2 }

            val pagerState = rememberPagerState(
                pageCount = { virtualPageCount },
                initialPage = initialVirtualPage
            )

            LaunchedEffect(pagerState, realPageCount) {
                // Collect from the a snapshotFlow reading the currentPage
                snapshotFlow { pagerState.currentPage }.collect { page ->
                    // Do something with each page change, for example:
                    // viewModel.sendPageSelectedEvent(page)
                    val realPage = if (realPageCount > 0) {
                        page % realPageCount
                    } else 0
                    "翻页了 -->  realPage:${realPage},page:$page,initPage: $initialVirtualPage,realPageCount: $realPageCount".logd()
                    if (realPageCount > 0) {
                        viewModel.onUiEvent(MusicUiEvent.SelectedMusicChange(realPage))
                    }
                }
            }

            LaunchedEffect(autoNext) {
                if (autoNext > 0) {
//                    val targetRealPage = if ((pagerState.currentPage + 1) >= musicListState.size) 0 else pagerState.currentPage + 1
                    val targetRealPage = pagerState.currentPage + 1
//                    val targetVirtualPage = (pagerState.currentPage / realPageCount) * realPageCount + targetRealPage
                    pagerState.scrollToPage(targetRealPage)
                }
            }

            LaunchedEffect(mediaItemIndex) {
                val cPage = pagerState.currentPage
                val realPage = if (realPageCount > 0) {
                    cPage % realPageCount
                } else 0
                "mediaItemIndex:$mediaItemIndex,pageInde:${realPage},cPage:$cPage".logd()
                if (mediaItemIndex != realPage){
                    val targetRealPage = (mediaItemIndex - realPage) + cPage
                    pagerState.scrollToPage(targetRealPage)
                }
            }

            val scope = rememberCoroutineScope()

            LocalMusicTheme {

                val permissionState = rememberPermissionState(
                    permission = if (Build.VERSION.SDK_INT >= 33) {
                        Manifest.permission.READ_MEDIA_AUDIO
                    } else Manifest.permission.READ_EXTERNAL_STORAGE
                )

                val lifecycleOwner = LocalLifecycleOwner.current

                val isGranted by remember {
                    derivedStateOf {
                        permissionState.status.isGranted
                    }
                }

                DisposableEffect(lifecycleOwner) {
                    val observer = LifecycleEventObserver { _, event ->
                        if (event == Lifecycle.Event.ON_RESUME) {
                            permissionState.launchPermissionRequest()
//                            "请求了权限。${permissionState.status.isGranted}".logd()
                        } else if (event == Lifecycle.Event.ON_DESTROY) {
                            "activity onDestroy".logd()
                        }
                    }
                    lifecycleOwner.lifecycle.addObserver(observer)
                    onDispose {
                        lifecycleOwner.lifecycle.removeObserver(observer)
                    }
                }

                val isLoading by viewModel.isDataLoading.collectAsStateWithLifecycle()

                val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.loading))
                val lottieAnimatable = rememberLottieAnimatable()

                LaunchedEffect(isLoading) {
                    if (isLoading) {
                        lottieAnimatable.animate(
                            composition,
//                            iterations = 1,
                            iterations = LottieConstants.IterateForever,
                            speed = 1f
                        )
                    }
                }


                Scaffold(
                    modifier = Modifier.fillMaxSize(),
                    snackbarHost = {
                        SnackbarHost(
                            hostState = snackbarHostState,
                            modifier = Modifier
                                .width(360.dp),
                            snackbar = {
                                Snackbar(
//                            snackbarData = it,
                                    shape = RoundedCornerShape(10.dp),
                                    containerColor = SnackbarDefaults.color.copy(0.85f),
                                    content = {
                                        Row(
                                            modifier = Modifier.width(360.dp),
                                            verticalAlignment = Alignment.CenterVertically,
                                            horizontalArrangement = Arrangement.Center
                                        ) {
                                            Text(
                                                text = it.visuals.message
                                            )
                                        }
                                    }
                                )
                            }
                        )
                    },
                    floatingActionButton = {
                        FloatingActionButton(
                            onClick = {
                                if (musicListState.isEmpty()) {
                                    msg = this.getString(R.string.music_list_is_empty)
                                } else {
                                    showListDialog = true
                                }
                            },
                            modifier = Modifier
//                                .align(Alignment.BottomEnd)
                                .padding(end = 26.dp, bottom = 66.dp)
                        ) {
                            Icon(
                                imageVector = Icons.AutoMirrored.Filled.QueueMusic,
                                contentDescription = null
                            )
                        }
                    }
                ) { innerPadding ->

                    val brush = Brush.linearGradient(
                        listOf(
                            Color(0xffb92b27),
                            Color(0xff1565C0)
                        )
                    )

                    if (!isGranted) {
                        Column(
                            modifier = Modifier
                                .fillMaxSize()
                                .padding(innerPadding),
                            horizontalAlignment = Alignment.CenterHorizontally,
                            verticalArrangement = Arrangement.Center
                        ) {
                            Text(
                                text = stringResource(R.string.no_permission),
                                style = TextStyle(
                                    fontSize = MaterialTheme.typography.labelLarge.fontSize
                                )
                            )
                            Spacer(Modifier.height(8.dp))
                            Button(
                                onClick = {
                                    getPermission()
                                }
                            ) {
                                Text(
                                    text = stringResource(R.string.go_to_setting),
                                    fontSize = MaterialTheme.typography.labelMedium.fontSize
                                )
                            }
                        }
                    } else {
                        LaunchedEffect(Unit) {
                            viewModel.getLocalMusicList()
                        }
                        Box(
                            modifier = Modifier
                                .fillMaxSize()
                                .background(brush)
                        ) {
                            if (musicListState.isEmpty()) {
                                MusicItemComponent(
                                    imageUrl = imageModel.url,
                                    audioItem = AudioItem(
                                        id = 0,
                                        uri = Uri.EMPTY,
                                        displayName = "audio",
                                        artist = "artist",
                                        duration = 0,
                                        title = "title",
                                        data = "data",
                                        artWork = null
                                    ),
                                    currentPosition = currentPosition
                                )
                            } else {
                                VerticalPager(
                                    state = pagerState
                                ) { page ->
                                    val realPage = remember(page) {
                                        if (realPageCount > 0) {
                                            page % realPageCount
                                        } else 0
                                    }

                                    val audioItem = remember(realPage) {
                                        musicListState[realPage]
                                    }
//                                    LaunchedEffect(realPage) {
//                                        "翻页了 -->当前页为 $page,realPage为 $realPage".logd()
//                                    }
                                    MusicItemComponent(
                                        audioItem = audioItem,
                                        currentPosition = currentPosition,
                                        isPlaying = isPlaying,
                                        imageUrl = imageModel.url,
                                        refreshAiImage = {
                                            viewModel.onUiEvent(MusicUiEvent.RefreshAiImage)
                                        },
                                        playPause = {
                                            viewModel.onUiEvent(PlayPause)
                                        },
                                        forward = {
                                            viewModel.onUiEvent(Forward)
                                        },
                                        backward = {
                                            viewModel.onUiEvent(Backward)
                                        },
                                        next = {
//                                            viewModel.onUiEvent(SeekToNext)
                                            scope.launch {
//                                                val targetRealPage = if ((pagerState.currentPage + 1) >= musicListState.size) 0 else pagerState.currentPage + 1
                                                val targetRealPage = pagerState.currentPage + 1
                                                pagerState.scrollToPage(targetRealPage)
                                            }
                                        },
                                        previous = {
                                            scope.launch {
//                                                val targetRealPage = if ((pagerState.currentPage - 1) < 0) musicListState.size - 1 else pagerState.currentPage - 1
                                                val targetRealPage = pagerState.currentPage - 1
                                                pagerState.scrollToPage(targetRealPage)
                                            }
//                                            viewModel.onUiEvent(SeekToPrevious)
                                        }
                                    )
                                }
                            }


                            if(isLoading){
                                Box(
                                    modifier = Modifier.fillMaxSize()
                                        .background(Color.Black.copy(0.7f))
                                        .clickable(
                                            onClick = {},
                                            interactionSource = remember { MutableInteractionSource() },
                                            indication = null
                                        ),
                                    contentAlignment = Alignment.Center
                                ){
                                    LottieAnimation(
                                        composition = composition,
                                        progress = { lottieAnimatable.progress },
                                        modifier = Modifier.size(200.dp),
                                        safeMode = true
                                    )
                                }
                            }

                        }

                    }
                }

                if (showListDialog) {
                    MusicListDialog(
                        musicList = musicListState,
                        onItemClicked = {
                            val targetRealPage = musicListState.indexOf(it)

                            if (targetRealPage != -1) {
                                val targetVirtualPage =
                                    (pagerState.currentPage / realPageCount) * realPageCount + targetRealPage
                                scope.launch {
                                    pagerState.scrollToPage(targetVirtualPage)
                                }
                            }
                            showListDialog = false
                        }
                    ) {
                        showListDialog = false
                    }
                }
            }
        }
    }

    private fun startMusicService() {
        if (!isServiceRunning) {
            val intent = Intent(this, PlaybackService::class.java)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                startForegroundService(intent)
            } else {
                startService(intent)
            }
            isServiceRunning = true
        }
    }


    override fun onDestroy() {
        super.onDestroy()
        "activity onDestroy".logd()
    }

}